package com.ty.user.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ty.user.pojo.UserInfo;
import com.ty.user.mapper.UserInfoMapper;
import com.ty.user.service.UserInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ty.user.utils.ConstantPropertiesUtils;
import com.ty.user.utils.RandomUtil;
import com.ty.utils.MD5;
import com.ty.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.rmi.ServerException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author wxq
 * @since 2023-02-21
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Resource
    private UserInfoMapper userInfoMapper;


    /**
     * 发送短信验证码
     */
    @Override
    public boolean sendCode(String phone) {
        // 生成验证码，
       String code = RandomUtil.getSixBitRandom();

        //判断手机号是否为空
        if(StringUtils.isEmpty(phone)) {
            return false;
        }
        //整合阿里云短信服务
        //设置相关参数
        DefaultProfile profile = DefaultProfile.
                getProfile(ConstantPropertiesUtils.REGION_Id,
                        ConstantPropertiesUtils.ACCESS_KEY_ID,
                        ConstantPropertiesUtils.SECRECT);
        IAcsClient client = new DefaultAcsClient(profile);
        CommonRequest request = new CommonRequest();
        //request.setProtocol(ProtocolType.HTTPS);
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendSms");

        //手机号
        request.putQueryParameter("PhoneNumbers", phone);
        //签名名称
        request.putQueryParameter("SignName", "天翊桉");
        //模板code
        request.putQueryParameter("TemplateCode", "SMS_270295315");
        //验证码  使用json格式   {"code":"123456"}
        Map<String,Object> param = new HashMap();
        param.put("code",code);
        request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param));

        // 将该手机号在redis中的作为key的值清除（将该手机之前发送的验证码清除掉）
        redisTemplate.delete(phone);
        // 将验证码存入redis中
        redisTemplate.opsForValue().set(phone, code, 15, TimeUnit.MINUTES);

        //调用方法进行短信发送
        try {
            CommonResponse response = client.getCommonResponse(request);
            System.out.println(response.getData());
            response.getHttpResponse().isSuccess();
            return true;
        } catch (ClientException e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * 手机号登录
     * @param map
     * @return
     */
    @Override
    public R phoneLogin(HashMap<String, String> map) {
        // 获取手机号和短信验证码
        String phone = map.get("phone");
        String smsCode = map.get("smsCode");

        // 通过手机号从redi缓存中获取短信验证码
        Object redisCode = redisTemplate.opsForValue().get(phone);
        redisTemplate.delete(phone);

        if (redisCode == null) {
            return R.ok().message("验证码已失效！");
        }

        // 将用户输入的验证码与redis中的验证码进行对比
        if (!smsCode.equals(redisCode)) {
            return R.ok().message("验证码输入错误！");
        }

        // 获取绑定类型
        String bindingType = map.get("bindingType");

        // token
        String token = null;

        // 根据手机号查询数据
        QueryWrapper phoneQW = new QueryWrapper();
        phoneQW.eq("phone", phone);
        UserInfo phoneInfo = userInfoMapper.selectOne(phoneQW);

        // 查询出来的手机数据判断是否为空
        if (phoneInfo == null) {
            // 手机数据为空

            // 初始化插入数据的userinfo
            UserInfo userInfo = initUser();

            // 判断绑定类型
            // 如果其中一个不为空，那么将手机号一起插入数据
            if (bindingType.equals("wx")) {
                // 获取微信数据
                String openid = map.get("openid");
                String nickName = map.get("nickName");
                String headPortraitUrl = map.get("headPortraitUrl");

                // 填充数据
                userInfo.setOpenid(openid);
                userInfo.setNickName(nickName);
                userInfo.setHeadPortraitUrl(headPortraitUrl);

            } else if (bindingType.equals("account")) {
                // 获取账号密码
                String userName = map.get("userName");
                String password = map.get("password");
                // 将密码加密
                String newPassword  = MD5.encrypt(password);

                // 填充数据
                userInfo.setUserName(userName);
                userInfo.setPassword(newPassword);

            } else {

                //插入手机相关的数据
                userInfo.setPhone(phone);

            }

            // 将数据插入数据库
            int insert = userInfoMapper.insert(userInfo);

            if (insert > 0) {
                return R.ok().message("登录成功")
                        .data("userInfo", userInfo)
                        .data("token", token);
            }




        } else {
            // 手机数据不为空

            // 判断绑定类型
            // 如果其中一个不为空，那么基于手机号数据修改数据
            if (bindingType.equals("wx")) {
                // 获取微信数据
                String openid = map.get("openid");
                String nickName = map.get("nickName");
                String headPortraitUrl = map.get("headPortraitUrl");

                // 判断手机数据中的openid是否为空，与传过来的值是否相同
                if (org.apache.commons.lang3.StringUtils.isNotBlank(phoneInfo.getOpenid())) {
                    if (!phoneInfo.getOpenid().equals(openid)) {
                        // 不相同，返回前端提醒用户该手机号已被别的微信账号绑定
                        return R.ok().message("改手机号已被绑定！");
                    }
                }

                // 填充数据
                phoneInfo.setOpenid(openid);
                phoneInfo.setNickName(nickName);
                phoneInfo.setHeadPortraitUrl(headPortraitUrl);
            } else if (bindingType.equals("account")) {
                // 获取账号密码
                String userName = map.get("userName");
                String password = map.get("password");
                // 将密码加密
                String newPassword  = MD5.encrypt(password);

                // 填充数据
                phoneInfo.setUserName(userName);
                phoneInfo.setPassword(newPassword);

            } else {

            }

            // 账号密码为空与openid为空

        }




        // 如果openid不为空，如果手机数据不为空

        // 相同，修改数据




        return null;
    }

    /**
     * 账号密码登录
     * @param map
     * @return
     */
    @Override
    public UserInfo accountLogin(HashMap<String, String> map) {
        // 获取账号和密码

        // 将密码加密
        // 根据账号和密码密文查询数据

        // 数据不为空，生成token返回前台

        // 数据为空，将数据返回前台
        return null;
    }

    public UserInfo initUser() {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(Long.parseLong(IdUtil.simpleUUID()));
        userInfo.setRoleId(1L);
        userInfo.setAuthStatus(0);
        userInfo.setStatus(1);
        userInfo.setCreateId(userInfo.getId());
        userInfo.setCreateTime(DateUtil.date());
        userInfo.setUpdateId(userInfo.getId());
        userInfo.setUpdateTime(DateUtil.date());
        userInfo.setIsDeleted(0);
        userInfo.setVersion(1);
        return userInfo;
    }
}
